import sys
import re
# 数据库包写成如下是为了打包程序pyinstaller的
from pymssql import _mssql
from pymssql import _pymssql
import uuid
import decimal
# 导入excel操作的包
# import pandas as pd
import xlwings as xw
from PySide6.QtWidgets import QApplication, QMessageBox, QFileDialog
from PySide6.QtUiTools import QUiLoader


# 登录类

class LoginWindow:
    def __init__(self):
        # 从文件中加载UI定义

        # 从 UI 定义中动态 创建一个相应的窗口对象
        # 注意：里面的控件对象也成为窗口对象的属性了
        # 比如 self.ui.button , self.ui.textEdit
        self.ui = QUiLoader().load('W_login.ui')
        self.ui.btn_login.clicked.connect(self.handle_login)

    def handle_login(self):

        self.Users_name = self.ui.input_user.text().strip()
        pwd = self.ui.input_pwd.text().strip()
        print('name:', self.Users_name)
        # 验证用户登录
        import sqlite3
        conn = sqlite3.connect('test.db')
        c = conn.cursor()
        sql_str = "select password from Users where name='{}' ".format(self.Users_name)
        cursor = c.execute(sql_str)
        query_pwd = cursor.fetchone()
        # print(query_pwd[0])
        print(type(query_pwd))
        if query_pwd and pwd == query_pwd[0]:
            self.ui.hide()
            self.owMainWindow = MainWindow()
            self.owMainWindow.ui.show()
        else:
            QMessageBox.critical(
                self.ui,
                '错误',
                '用户名或密码错误！！')


# 主窗口

class MainWindow:
    def __init__(self):
        self.ui = QUiLoader().load('W_MainWindow.ui')

        self.ui.action_importData.triggered.connect(self.openW_importData)
        print('打开导入数据窗口')

    def openW_importData(self):
        self.owImportData = ImportData()
        self.owImportData.ui.show()


# 导入数据类

class ImportData:
    def __init__(self):
        # 加载ui
        self.ui = QUiLoader().load('W_importData.ui')
        # excel数据转换按钮
        self.ui.selectedfile.clicked.connect(self.selectedFile)
        # 导入test.db按钮
        self.ui.importDB.clicked.connect(self.importDataBase)
        # 清空数据按钮
        self.ui.btn_cleanData.clicked.connect(self.clean_data)
        # 生成模板按钮generate template
        self.ui.btn_gTemplates.clicked.connect(self.generate_template)

    def generate_template(self):
        # 生成文件计数
        self.file_num = 1
        self.savePath = QFileDialog.getExistingDirectory(self.ui,"选择保存文件路径")
        print('self.savePath:',self.savePath)
        import sqlite3
        conn = sqlite3.connect('test.db')
        # 创建游标
        cursor = conn.cursor()
        # 创建插入数据语句，在下面的for循环里逐条插入
        DB_str = "select * from cutData"
        o_db = cursor.execute(DB_str)
        print(o_db)
        print(type(o_db))  # <class 'sqlite3.Cursor'>
        results = o_db.fetchall()
        print(type(results))  # list
        结果行数 = len(results)
        print(结果行数)
        for i in range(0, len(results)):
            # print(len(results[i]))
            # for a in range(1,len(results[i])):
            # print(results[i][1])
            # print(results[i][0])
            # 获取到数据库字段值

            mainData = results[i][2]
            print("mainData = ", mainData)
            standard_data = mainData.split(',')
            print(standard_data)

            queryData = results[i][1].split(',')


            try:
                # 导入xlwings模块，打开Excel程序，默认设置：程序可见，只打开不新建工作薄，屏幕更新关闭

                app = xw.App(visible=False, add_book=False)
                app.display_alerts = False
                app.screen_updating = False
                # 文件位置：filepath，打开test文档，然后保存，关闭，结束程序
                filepath = r'02__BN_Terminal_Crimping_Report__202106.xlsx'
                wb = app.books.open(filepath)
                # 打开第一个sheet页
                sheet = wb.sheets[0]
                # 新建sheet1，用来保存没有提供标准值的数据，如角度等
                sheet1 = wb.sheets['sheet1']
                # 向指定的单元格插入值
                # 线束供应商
                # sheet.range('B4').value = '长春一汽富晟李尔汽车电器有限公司'
                # print(sheet.range('B4').value)
                # 线束厂家代码
                # sheet.range('I4').value = '4VM'
                # 端子零件号
                sheet.range('B5').value = queryData[0]
                # 导线截面积
                sheet.range('F5').value = queryData[1]
                # 项目代码self.projectCode
                sheet.range('I5').value = queryData[2]
                # 端子供应商
                sheet.range('B6').value = queryData[3]
                # 剥头长度
                sheet.range('F6').value = standard_data[0]
                # 报告编号
                if standard_data[37]:
                    sheet.range('I6').value = standard_data[37]
                else:
                    sheet.range('I6').value = ''
                # 端子压接区厚度
                sheet.range('B7').value = standard_data[1]
                # 模具号
                sheet.range('F7').value = standard_data[4]
                # 模具供应商
                sheet.range('I7').value = standard_data[5]
                # --------------------------------------
                # 芯线压接高度
                芯线压接高度 = re.sub(u"([^\d+(\.\d+)?])", "", standard_data[6])
                if 芯线压接高度:
                    sheet.range('B10').value = 芯线压接高度
                else:
                    sheet.range('B10').value = ''
                ###sheet.range('B10').value = standard_data[6]
                # 芯线压接高度 上公差
                芯线压接高度上公差 = re.sub(u"([^\d+(\.\d+)?])", "", standard_data[7])
                if 芯线压接高度上公差:
                    sheet.range('C10').value = 芯线压接高度上公差
                else:
                    sheet.range('C10').value = ''
                ###sheet.range('C10').value = standard_data[7]
                # 芯线压接高度 下公差
                芯线压接高度下公差 = re.sub(u"([^\d+(\.\d+)?])", "", standard_data[8])
                if 芯线压接高度下公差:
                    sheet.range('C11').value = '-' + 芯线压接高度下公差
                else:
                    sheet.range('C11').value = ''
                ###sheet.range('C11').value = '-'+standard_data[8]
                # 绝缘压接高度
                绝缘压接高度 = re.sub(u"([^\d+(\.\d+)?])", "", standard_data[9])

                if 绝缘压接高度:
                    sheet.range('D10').value = 绝缘压接高度
                else:
                    sheet.range('D10').value = ''
                ###sheet.range('D10').value = standard_data[9]
                # 绝缘压接高度 上公差
                绝缘压接高度上公差 = re.sub(u"([^\d+(\.\d+)?])", "", standard_data[10])
                if 绝缘压接高度上公差:
                    sheet.range('E10').value = 绝缘压接高度上公差
                else:
                    sheet.range('E10').value = ''
                ###sheet.range('E10').value = standard_data[10]
                # 绝缘压接高度 下公差
                绝缘压接高度下公差 = re.sub(u"([^\d+(\.\d+)?])", "", standard_data[11])
                if 绝缘压接高度下公差:
                    sheet.range('E11').value = '-' + 绝缘压接高度下公差
                else:
                    sheet.range('E11').value = ''
                ###sheet.range('E11').value = '-'+standard_data[11]
                # 横截面宽度1
                横截面宽度1 = re.sub(u"([^\d+(\.\d+)?])", "", standard_data[12])
                if 横截面宽度1:
                    sheet.range('F10').value = 横截面宽度1
                else:
                    sheet.range('F10').value = ''
                ###sheet.range('F10').value = re.sub(u"([^\d+(\.\d+)?])", "",standard_data[12])
                # 横截面宽度1 上公差
                横截面宽度1上公差 = re.sub(u"([^\d+(\.\d+)?])", "", standard_data[13])
                if 横截面宽度1上公差:
                    sheet.range('G10').value = 横截面宽度1上公差
                else:
                    sheet.range('G10').value = ''
                ###sheet.range('G10').value = re.sub(u"([^\d+(\.\d+)?])", "",standard_data[13])
                # 横截面宽度1 下公差
                横截面宽度1下公差 = re.sub(u"([^\d+(\.\d+)?])", "", standard_data[14])
                if 横截面宽度1下公差:
                    sheet.range('G11').value = '-' + 横截面宽度1下公差
                else:
                    sheet.range('G11').value = ''
                # 导体拉拔力---------======----------
                导体拉拔力 = re.sub(u"([^\d+(\.\d+)?])", "", standard_data[15])
                print("导体拉拔力:", 导体拉拔力)
                sheet.range('H10').value = 导体拉拔力
                # ------------------------------------------------
                # 芯线压接宽度
                芯线压接宽度 = re.sub(u"([^\d+(\.\d+)?])", "", standard_data[16])
                if 芯线压接宽度:
                    sheet.range('B15').value = 芯线压接宽度
                else:
                    sheet.range('B15').value = ''
                ###sheet.range('B15').value = standard_data[16]
                # 芯线压接宽度 上公差
                芯线压接宽度上公差 = re.sub(u"([^\d+(\.\d+)?])", "", standard_data[17])
                if 芯线压接宽度上公差:
                    sheet.range('C15').value = 芯线压接宽度上公差
                else:
                    sheet.range('C15').value = ''
                ###sheet.range('C15').value = standard_data[17]
                # 芯线压接宽度 下公差
                芯线压接宽度下公差 = re.sub(u"([^\d+(\.\d+)?])", "", standard_data[18])
                if 芯线压接宽度下公差:
                    sheet.range('C16').value = '-' + 芯线压接宽度下公差
                else:
                    sheet.range('C16').value = ''
                print("下公差类型")
                print(type(standard_data[18]))
                ###sheet.range('C16').value = '-'+standard_data[18]
                # 绝缘压接宽度
                绝缘压接宽度 = re.sub(u"([^\d+(\.\d+)?])", "", standard_data[19])
                if 绝缘压接宽度:
                    sheet.range('D15').value = 绝缘压接宽度
                else:
                    sheet.range('D15').value = ''
                ### sheet.range('D15').value = standard_data[19]
                # 绝缘压接宽度 上公差
                绝缘压接宽度上公差 = re.sub(u"([^\d+(\.\d+)?])", "", standard_data[20])
                if 绝缘压接宽度上公差:
                    sheet.range('E15').value = 绝缘压接宽度上公差
                else:
                    sheet.range('E15').value = ''
                ###sheet.range('E15').value = standard_data[20]
                # 绝缘压接宽度 下公差
                绝缘压接宽度下公差 = re.sub(u"([^\d+(\.\d+)?])", "", standard_data[21])
                if 绝缘压接宽度下公差:
                    sheet.range('E16').value = '-' + 绝缘压接宽度下公差
                else:
                    sheet.range('E16').value = ''
                ###sheet.range('E16').value = '-'+standard_data[21]
                # 横截面宽度2
                sheet.range('F15').value = re.sub(u"([^\d+(\.\d+)?])", "", standard_data[22])
                # 横截面宽度2 上公差
                sheet.range('G15').value = re.sub(u"([^\d+(\.\d+)?])", "", standard_data[23])
                # 横截面宽度2 下公差
                横截面宽度2下公差 = re.sub(u"([^\d+(\.\d+)?])", "", standard_data[24])
                if 横截面宽度2下公差:
                    sheet.range('G16').value = '-' + 横截面宽度2下公差
                else:
                    sheet.range('G16').value = ''
                # 翼翅压接状态
                sheet.range('H17').value = 'Yes'
                # -------------------------------------------------
                # 支撑角度 sub_str = re.sub(u"([^\u4e00-\u9fa5\u0030-\u0039\u0041-\u005a\u0061-\u007a])","",string)
                支撑角度 = re.sub(u"([^\d+(\.\d+)?])", "", standard_data[25])
                if 支撑角度:
                    sheet1.range('B2').value = 支撑角度
                else:
                    sheet.range('B19').value = ''
                # 端子侧面弯曲度 re.sub(u"([^\d+(\.\d+)?])"
                端子侧面弯曲度 = re.sub(u"([^\d+(\.\d+)?])", "", standard_data[26])
                if 端子侧面弯曲度:
                    sheet1.range('D2').value = 端子侧面弯曲度
                else:
                    sheet.range('D19').value = ''
                # 翼翅端面间隙1
                翼翅端面间隙1 = re.sub(u"([^\d+(\.\d+)?])", "", standard_data[27])
                if 翼翅端面间隙1:
                    sheet1.range('F2').value = 翼翅端面间隙1
                else:
                    sheet.range('F19').value = ''
                # 翼翅末端距离1
                翼翅末端距离1 = re.sub(u"([^\d+(\.\d+)?])", "", standard_data[28])
                if 翼翅末端距离1:
                    sheet1.range('H2').value = 翼翅末端距离1
                else:
                    # 绝对值的x1，不用填数
                    sheet.range('H19').value = ''
                # 毛刺高度
                毛刺高度 = re.sub(u"([^\d+(\.\d+)?])", "", standard_data[29])
                if 毛刺高度:
                    sheet1.range('I2').value = 毛刺高度
                else:
                    sheet.range('I19').value = ''
                # ==============================================
                # 支撑高度
                支撑高度 = re.sub(u"([^\d+(\.\d+)?])", "", standard_data[30])
                if 支撑高度:
                    sheet1.range('B4').value = 支撑高度
                else:
                    sheet.range('B21').value = ''
                # 端子正面弯曲度
                端子正面弯曲度 = re.sub(u"([^\d+(\.\d+)?])", "", standard_data[31])
                if 端子正面弯曲度:
                    sheet1.range('D4').value = 端子正面弯曲度
                else:
                    sheet.range('D21').value = ''
                # 翼翅端面间隙2
                翼翅端面间隙2 = re.sub(u"([^\d+(\.\d+)?])", "", standard_data[32])
                if 翼翅端面间隙2:
                    sheet1.range('F4').value = 翼翅端面间隙2
                else:
                    sheet.range('F21').value = ''
                # 翼翅末端距离2
                # if '＜＝' in standard_data[33]:
                #     sheet1.range('H4').value = standard_data[33].replace('＜＝', '')
                # else:
                #     sheet.range('H21').value = ''
                # 毛刺宽度
                毛刺宽度 = re.sub(u"([^\d+(\.\d+)?])", "", standard_data[34])
                print(毛刺宽度)
                if 毛刺宽度:
                    sheet1.range('I4').value = 毛刺宽度
                else:
                    sheet.range('I21').value = ''
                # ==============================================
                # 压接基底厚度
                压接基底厚度 = re.sub(u"([^\d+(\.\d+)?])", "", standard_data[35])
                if 压接基底厚度:
                    sheet1.range('B6').value = 压接基底厚度
                else:
                    sheet.range('B23').value = ''
                # CFE=X1-X2
                做差项 = re.sub(u"([^\d+(\.\d+)?])", "", standard_data[36])
                if 做差项:
                    sheet1.range('J4').value = 做差项
                else:
                    sheet.range('I18').value = ''
                    sheet.range('I20').value = ''
                # 端子对应的模块号

                # sheet.range('G25').value = self.modu_datas
                # 压接剖面形状
                # sheet.range('D23').value = ''
                # 线芯呈蜂窝状
                # sheet.range('F23').value = ''
                # 无压接裂纹
                # sheet.range('H23').value = ''
                # 股丝未漏出
                # sheet.range('I23').value = ''
                # 填写零件号
                # sheet.range('J43').value = standard_data[-1]
                # ==============================================
                # 一汽-大众
                sheet.range('I46').value = standard_data[-1]
                # 保存文件，添加路径及文件名为另存文件

                pathFile = self.savePath + '/' + queryData[0] + '-' + queryData[1] + '-' + queryData[3] + '.xlsx'
                print(pathFile)
                wb.save(r'{}'.format(pathFile))

                # 关闭工作薄
                wb.close()
                # 关闭应用
                app.quit()


            except:
                # 关闭工作薄
                wb.close()
                # 关闭应用
                app.quit()
        # 提交命令
        conn.commit()
        # 关闭连接
        conn.close()
        QMessageBox.about(self.ui,
                          '提示',
                          "操作成功！共生成{}个文件".format(结果行数)
                          )

    def clean_data(self):
        import sqlite3
        # 创建数据库连接
        conn = sqlite3.connect('test.db')
        # 创建游标
        cursor = conn.cursor()
        # 创建插入数据语句，在下面的for循环里逐条插入
        insertDB_str = "delete from cutData"
        cursor.execute(insertDB_str)
        conn.commit()
        conn.close()
        # 执行完提示
        QMessageBox.about(self.ui,
                          '提示',
                          f'''数据删除成功！'''
                          )

    def selectedFile(self):
        # 获取打开文件或excel的路径及文件名
        sltfile = QFileDialog.getOpenFileName()
        print('打开参数文件路径', sltfile)
        # 实例化一个excel应用
        # 默认设置：程序可见，只打开不新建工作薄，屏幕更新关闭
        app = xw.App(visible=False, add_book=False)
        app.display_alerts = False
        app.screen_updating = False
        filepath = sltfile[0]
        # 通过app对象调用books的open方法
        wb = app.books.open(filepath)
        # 打开第一个sheet页
        try:
            sheet = wb.sheets[0]
            # 通过sheet对象获取使用的范围
            rng_info = sheet.used_range
            # 用范围对象获取到行，在得到所有的行数。
            row_counts = rng_info.rows.count
            print(row_counts)
            # 用app对象，调用工作簿来新建表格
            wbn = app.books.add()
            for i in range(2, row_counts + 1):
                print(i)
                # 转化sheet.range()内的参数
                # 获取单行数据
                rng_str1 = 'C{}:F{}'.format(i, i)
                rng_str2 = 'G{}:AT{}'.format(i, i)
                #为excel的cell赋值
                queryData_list = sheet.range(rng_str1).value
                mainData_list = sheet.range(rng_str2).value
                # queryData_list为list，下面是将列表抓换为‘，’分隔的字符串
                print(queryData_list)
                print(mainData_list)
                #用for 和join 把列表转换字符串
                queryData = ",".join(str(i1) for i1 in queryData_list)
                mainData = ",".join(str(j1) for j1 in mainData_list)
                print(type(queryData))
                #定义要插入数据的表格坐标eg:heets['sheet1'].range('A1:B1').value
                rng_str3 = 'A{}'.format(i)
                rng_str4 = 'B{}'.format(i)
                # 过滤下值为None，使之不写入
                if all(x is not None for x in queryData_list):
                    # 向单元格中插入数据
                    wbn.sheets['sheet1'].range(rng_str3).value = queryData.upper()
                    wbn.sheets['sheet1'].range(rng_str4).value = mainData

            # 保存表格
            wbn.save(filepath+'-result.xlsx')
            # 关闭工作薄

            wbn.close()
            wb.close()
            # 关闭应用
            app.quit()
            #执行完提示
            QMessageBox.about(self.ui,
                              '提示',
                              f'''操作成功！'''
                              )
        except:
            # 关闭工作薄

            wbn.close()
            wb.close()
            # 关闭应用
            app.quit()
            # 执行完提示
        # QApplication.exit()

    # 获取清洗后的excel标准参数，并导入到数据库
    def importDataBase(self):
        # 创建sqlserver数据库连接
        # conn = _pymssql.connect('10.71.216.85', 'sa', 'sa', 'CutReport')
        import sqlite3
        conn = sqlite3.connect('test.db')

        if conn:
            # 创建游标
            cursor = conn.cursor()
            # 创建插入数据语句，在下面的for循环里逐条插入
            insertDB_str = "INSERT INTO cutData ( queryData ,mainData ) VALUES('{}','{}')"
            # 获取文件名及路径
            inXLpath = QFileDialog.getOpenFileName()
            print('结果文件路径', inXLpath)
            # 实例化一个excel应用
            # 默认设置：程序可见，只打开不新建工作薄，屏幕更新关闭
            app = xw.App(visible=False, add_book=False)
            app.display_alerts = False
            app.screen_updating = False
            filepath = inXLpath[0]
            # 通过app对象调用books的open方法
            wb = app.books.open(filepath)
            # 打开第一个sheet页
            try:
                sheet = wb.sheets[0]
                # 通过sheet对象获取使用的范围
                rng_info = sheet.used_range
                # 用范围对象获取到行，在得到所有的行数。
                row_counts = rng_info.rows.count
                print('表格行数：', row_counts)
                # 遍历循环出说有行数据

                # a2-a108
                for i in range(2, row_counts + 2):
                    print(i)
                    # 转化sheet.range()内的参数
                    # 获取表格坐标
                    rng_strA = 'A{}'.format(i)
                    rng_strB = 'B{}'.format(i)
                    # 获取单元格内的值

                    queryData_list = sheet.range(rng_strA).value
                    mainData_list = sheet.range(rng_strB).value
                    print(queryData_list, mainData_list)
                    insert_str = insertDB_str.format(queryData_list, mainData_list)
                    print(insert_str)
                    cursor.execute(insert_str)
                    conn.commit()
                # 关闭游标
                cursor.close()
                # 关闭连接
                conn.close()
                # 关闭表格对象
                wb.close()
                # 关闭应用
                app.quit()
                # 执行完提示
                QMessageBox.about(self.ui,
                                  '提示',
                                  f'''操作成功！'''
                                  )
            except:
                # 关闭工作薄
                wb.close()
                # 关闭应用
                app.quit()
        else:
            QMessageBox.about(self.ui,
                              '提示',
                              f'''数据库连接失败，可能没连网！'''
                              )


if __name__ == '__main__':
    app = QApplication(sys.argv)
    win = LoginWindow()
    win.ui.show()
    sys.exit(app.exec())
